package mspbots.cw.data.core.reports;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.cw.common.ResultMsg;
import mspbots.cw.common.report.ReportNames;
import mspbots.cw.data.core.AbstractToolsUtil;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;

/**
 * com.mspbots.core.amqp.receivers.SchedulesReceiver
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/10/11
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class ReportsReceiver extends AbstractToolsUtil {

    private final ReportNames reportNames = ReportNames.names();

    private final ReportsRepository reportsRepository;

    @RabbitListener(queues = "connect-wise.reports.sync")
    public void processMsg(ResultMsg resultMsg) {

        Optional<Report> dataOpt = reportNames.keySet().stream().filter(k -> k.equals(resultMsg.getAction()))
                .map(k -> Report.builder()
                        .otherId(resultMsg.getId())
                        .name(resultMsg.getAction())
                        .tenantId(resultMsg.getTenantId())
                        .extend(resultMsg.getEntity())
                        .syncTime(resultMsg.getSyncDate())
                        .updateTime(LocalDateTime.parse(resultMsg.getEntity().get(reportNames.get(k)).asText(),
                                DateTimeFormatter.ISO_DATE_TIME))
                        .build())
                .findAny();

        Report data = dataOpt.orElseThrow();

        this.reportsRepository.findByOtherIdAndTenantIdAndName(data.getOtherId(), data.getTenantId(), data.getName())
                .switchIfEmpty(this.reportsRepository.save(data))
                .filter(old -> old.getUpdateTime().isBefore(data.getUpdateTime()))
                .map(result -> {
                    data.setId(result.getId());
                    data.setCreateTime(result.getCreateTime());
                    return data;
                })
                .flatMap(this.reportsRepository::save).block(Duration.ofSeconds(10));

    }
}
